package tw.cuttle.handler;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Map;

import tw.cuttle.CuttleContext;
import tw.cuttle.bean.Action;
import tw.cuttle.bean.Cache;
import tw.cuttle.bean.Process;
import tw.cuttle.bean.ProcessException;
import tw.cuttle.exception.ActionExecutionException;
import tw.cuttle.process.ProcessStrategy;
import tw.cuttle.process.ViewStrategy;

/**
 * @author andy.chuang
 * 
 */
public class ProcessHandler {
    private static ProcessStrategy processStrategy = new ProcessStrategy();
    private static ViewStrategy viewStrategy = new ViewStrategy();

    public void execute(Process process) throws ActionExecutionException {
	if (CuttleContext.getBeanHolder().getSetting().getEnv().getEnableCache() && process.getExec() != null
		&& process.getExec().length() > 0) {
	    if (process.getCache() != null) {
		Action currentAction = CuttleContext.getActionContext().getActionHelper().getCurrentAction();
		String actionProcessId = currentAction.getId() + "-" + process.getId();
		String cacheId = process.getCache().getId();
		String appendParameter = process.getCache().getAppendParameter();
		Integer timeout = process.getCache().getTimeout();
		Map<String, String> requestMap = CuttleContext.getActionContext().getActionHelper().getRequest()
			.getParameterMap();
		if (process.getCache().getType().equals(Cache.CACHE_TYPE.file.name())) {
		    Boolean isTimeout = CuttleContext.getProcessContext().getJspCacheManager().isTimeout(
			    cacheId,
			    CuttleContext.getProcessContext().getJspCacheManager().getKey(cacheId, actionProcessId,
				    appendParameter, requestMap), timeout);
		    if (isTimeout) {
			processStrategy.getStrategy(CuttleContext.getBeanHolder().getSetting().getEnv().getStrategy())
				.methodInvoke(process);
		    }
		} else if (process.getCache().getType().equals(Cache.CACHE_TYPE.memory.name())) {

		    Boolean isTimeout = CuttleContext.getProcessContext().getJspCacheManager().isTimeout(
			    cacheId,
			    CuttleContext.getProcessContext().getJspCacheManager().getKey(cacheId, actionProcessId,
				    appendParameter, requestMap), timeout);
		    if (isTimeout) {
			processStrategy.getStrategy(CuttleContext.getBeanHolder().getSetting().getEnv().getStrategy())
				.methodInvoke(process);
			CuttleContext.getProcessContext().getJspCacheManager().addCache(
				CuttleContext.getProcessContext().getJspCacheManager().getKey(cacheId, actionProcessId,
					appendParameter, requestMap), null, timeout);
		    }
		}

	    } else {
		processStrategy.getStrategy(CuttleContext.getBeanHolder().getSetting().getEnv().getStrategy())
			.methodInvoke(process);
	    }
	}

    }

    public void executeException(ProcessException processException) {
	processStrategy.getStrategy(CuttleContext.getBeanHolder().getSetting().getEnv().getStrategy()).methodInvoke(
		processException);
    }

    public String evaluateView(Process process) {
	Action currentAction = CuttleContext.getActionContext().getActionHelper().getCurrentAction();
	System.out.println("currentAction:"+currentAction);
	String actionProcessId = currentAction.getId() + "-" + process.getId();
	Map<String, String> requestMap = CuttleContext.getActionContext().getActionHelper().getRequest()
		.getParameterMap();
	String content=null;
	Cache cache=process.getCache();
	if(cache!=null){
		String cacheId = cacheId=process.getCache().getId();
		String appendParameter = process.getCache().getAppendParameter();
		Integer timeout = process.getCache().getTimeout();;
		
		
		Boolean isTimeout = CuttleContext.getProcessContext().getJspCacheManager().isTimeout(
			cacheId,
			CuttleContext.getProcessContext().getJspCacheManager().getKey(cacheId, actionProcessId,
				appendParameter, requestMap), timeout);
	
		if (process.getCache().getType().equals(Cache.CACHE_TYPE.file.name())) {
		    if (isTimeout) {
			content = viewStrategy.getStrategy(process.getViewType()).evaluateView(process);
			CuttleContext.getProcessContext().getJspCacheManager().addFileCache(
				CuttleContext.getProcessContext().getJspCacheManager().getKey(cacheId, actionProcessId,
					appendParameter, requestMap), content, timeout);
		    } else {
			File file = CuttleContext.getProcessContext().getJspCacheManager().getFileContent(cacheId,
				actionProcessId, appendParameter, requestMap);
			try {
			    InputStream is = new FileInputStream(file);
			    Reader reader = new InputStreamReader(is, "UTF-8");
			    BufferedReader br = new BufferedReader(reader);
			    StringBuffer sb = new StringBuffer();
			    int i;
	
			    while ((i = br.read()) != -1)
				sb.append((char) i);
			    is.close();
			    reader.close();
			    content = sb.toString();
			} catch (Exception e) {
			    // TODO
			    e.printStackTrace();
			}
	
		    }
		} else if (process.getCache().getType().equals(Cache.CACHE_TYPE.memory.name())) {
		    if (isTimeout) {
			content = viewStrategy.getStrategy(process.getViewType()).evaluateView(process);
			CuttleContext.getProcessContext().getJspCacheManager().addCache(
				CuttleContext.getProcessContext().getJspCacheManager().getKey(cacheId, actionProcessId,
					appendParameter, requestMap)
				, content, timeout);
		    }else{
			content=CuttleContext.getProcessContext().getJspCacheManager().getContent(cacheId, actionProcessId, appendParameter,
		    		    requestMap);
		    }
		}
	}else{
		content = viewStrategy.getStrategy(process.getViewType()).evaluateView(process);
	}
	return content;
    }

    public String evaluateView(ProcessException processException) {
	return viewStrategy.getStrategy(processException.getViewType()).evaluateView(processException);
    }
}
